package service

import (
	"encoding/json"
	"errors"
	"github.com/e421083458/gorm"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"github.com/gogf/gf/util/gconv"
	"rock/customer/dto"
	"rock/customer/initParam"
	"rock/customer/models"
	"rock/customer/modules/redisModules"
	"rock/customer/public"
	"time"
)

type Service struct {
}

// 关键词
func (s *Service) KeyWordList(gc *gin.Context, tx *gorm.DB) (data []dto.KeyWord, err error) {
	// 取缓存
	redisCache := redisModules.ClientRedis.Get(initParam.KeyWordListPrefix)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbImKeyword{}).
		Where("deleted = 2").Scan(&data).Error
	if err != nil {
		if err.Error() != gorm.ErrRecordNotFound.Error() {
			err = errors.New(initParam.DataIsNotExist)
			return
		}
	}
	if len(data) == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.KeyWordListPrefix, 15*24*time.Hour)
	return
}

// 关键词 - 发送
func (s *Service) KeyWordListWord(gc *gin.Context, tx *gorm.DB) (data []dto.KeyWord, err error) {
	keyWordList, errs := s.KeyWordList(gc, tx)
	err = errs
	if err != nil {
		return
	}
	for _, v := range keyWordList {
		if v.DataFlag == 2 {
			data = append(data, v)
		}
	}
	return
}

// 关键词 - 跳转
func (s *Service) KeyWordListJump(gc *gin.Context, tx *gorm.DB) (data []dto.KeyWord, err error) {
	keyWordList, errs := s.KeyWordList(gc, tx)
	err = errs
	if err != nil {
		return
	}
	for _, v := range keyWordList {
		if v.DataFlag == 1 {
			data = append(data, v)
		}
	}
	return
}

// 自动回复
func (s *Service) ReplySetting(gc *gin.Context, tx *gorm.DB) (data dto.ReplySetting, err error) {
	// 取缓存
	redisCache := redisModules.ClientRedis.Get(initParam.ReplySettingPrefix)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbImReplySetting{}).Scan(&data).Error
	if err != nil {
		if err.Error() != gorm.ErrRecordNotFound.Error() {
			err = errors.New(initParam.DataIsNotExist)
			return
		}
	}
	if data.Id == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.ReplySettingPrefix, 15*24*time.Hour)
	return
}

// 配置信息
func (s *Service) Config(gc *gin.Context, tx *gorm.DB, key string) (data dto.Config, err error) {
	// 取缓存
	redisCache := redisModules.ClientRedis.Get(initParam.ConfigPrefix + gconv.String(key))
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	// 查db
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbImConfig{}).
		Where("`key` = ?", key).
		Scan(&data).Error
	// 存缓存
	err = addRedis(data, initParam.ConfigPrefix + gconv.String(key), 7*24*time.Hour)
	return
}

// 配置信息 - 创建
func (s *Service) CreateConfig(gc *gin.Context, tx *gorm.DB, msg *models.WkbImConfig) error {
	cr := tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbImConfig{}).Create(msg)
	return cr.Error
}

// 技能组 - 管理员
func (s *Service) SkillGroup(gc *gin.Context, tx *gorm.DB, groupId int, lastUserId int) (userDetailOutput dto.CustomerService, err error) {
	skill := models.WkbImSkillGroup{}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbImSkillGroup{}).
		Where("id = ?", groupId).
		Scan(&skill).Error
	switch skill.GroupStrategy {
	case 1: // 随机
		err = tx.SetCtx(public.GetGinTraceContext(gc)).
			Model(&models.WkbImCustomerService{}).
			Table("wkb_im_customer_service wcs").
			Select("wcs.uid as user_id,wcs.nickname,wud.avatar").
			Joins("LEFT JOIN wkb_im_customer_service_group wcsg ON wcsg.uid = wcs.uid").
			Joins("LEFT JOIN wkb_user_detail wud on wud.uid = wcs.uid").
			// 是否不能拉 身为客服 的自己
			//Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? and wcs.uid <> ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId, userId).
			Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId).
			Order("RAND()").
			First(&userDetailOutput).Error
		break
	case 2: // 优先级
		err = tx.SetCtx(public.GetGinTraceContext(gc)).
			Model(&models.WkbImCustomerService{}).
			Table("wkb_im_customer_service wcs").
			Select("wcs.uid as user_id,wcs.nickname,wud.avatar").
			Joins("LEFT JOIN wkb_im_customer_service_group wcsg ON wcsg.uid = wcs.uid").
			Joins("LEFT JOIN wkb_user_detail wud on wud.uid = wcs.uid").
			// 是否不能拉 身为客服 的自己
			//Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? and wcs.uid <> ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId, userId).
			Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId).
			Order("wcsg.weight DESC").
			First(&userDetailOutput).Limit(1).Error
		break
	case 3: // 轮流
		err = tx.SetCtx(public.GetGinTraceContext(gc)).
			Model(&models.WkbImCustomerService{}).
			Table("wkb_im_customer_service wcs").
			Select("wcs.uid as user_id,wcs.nickname,wud.avatar").
			Joins("LEFT JOIN wkb_im_customer_service_group wcsg ON wcsg.uid = wcs.uid").
			Joins("LEFT JOIN wkb_user_detail wud on wud.uid = wcs.uid").
			// 是否不能拉 身为客服 的自己
			//Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? and wcs.uid <> ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId, userId).
			Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? AND wcs.deleted = 2 AND wcsg.deleted = 2 and wcs.uid <> ?", groupId, lastUserId).
			Order("wcs.uid ASC").
			First(&userDetailOutput).Limit(1).Error
		if errors.Is(err, gorm.ErrRecordNotFound) {
			err = tx.SetCtx(public.GetGinTraceContext(gc)).
				Model(&models.WkbImCustomerService{}).
				Table("wkb_im_customer_service wcs").
				Select("wcs.uid as user_id,wcs.nickname,wud.avatar").
				Joins("LEFT JOIN wkb_im_customer_service_group wcsg ON wcsg.uid = wcs.uid").
				Joins("LEFT JOIN wkb_user_detail wud on wud.uid = wcs.uid").
				// 是否不能拉 身为客服 的自己
				//Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? and wcs.uid <> ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId, userId).
				Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId).
				Order("wcs.uid ASC").
				First(&userDetailOutput).Limit(1).Error
		}
	case 4: // 最少发言先
		err = tx.SetCtx(public.GetGinTraceContext(gc)).
			Model(&models.WkbImCustomerService{}).
			Table("wkb_im_customer_service wcs").
			Select("wcs.uid as user_id,wcs.nickname,wud.avatar").
			Joins("LEFT JOIN wkb_im_customer_service_group wcsg ON wcsg.uid = wcs.uid").
			Joins("LEFT JOIN wkb_user_detail wud on wud.uid = wcs.uid").
			// 是否不能拉 身为客服 的自己
			//Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? and wcs.uid <> ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId, userId).
			Where("wcs.is_manage = 1 and wcs.is_online = 1 and wcsg.group_id = ? AND wcs.deleted = 2 AND wcsg.deleted = 2 ", groupId).
			Order("wcsg.reception_num ASC").
			First(&userDetailOutput).Limit(1).Error
		break
	default:
		break
	}
	return
}

// 成就 - 数量
func (s *Service) AchievementNum(gc *gin.Context, tx *gorm.DB, userId string) (count int, err error) {
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbImAchievement{}).
		Where("uid = ? and status = 2", userId).Count(&count).Error
	return
}

// 成就 - 列表
func (s *Service) AchievementList(gc *gin.Context, tx *gorm.DB, userId string, pageNum int, pageSize int) (achievementList []dto.Integral, count int, err error) {
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbImAchievement{}).
		Where("uid = ? and status = 2", userId).Count(&count).Error
	if count == 0 {
		return
	}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbImAchievement{}).
		Where("uid = ? and status = 2", userId).Scan(&achievementList).
		//Limit(pageSize).Offset((pageNum - 1) * pageSize).
		Error
	return
}

// 报表 - 创建记录
func (s *Service) CreateReport(c *gin.Context, tx *gorm.DB, data *models.WkbImSessionReport) error {
	return tx.SetCtx(public.GetGinTraceContext(c)).Model(&models.WkbImSessionReport{}).Create(data).Error
}